# encoding: utf-8

module OJ
  module API
    # [GetKeyState](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getkeystate)
    # [Virtual-Key Codes](https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes)
    GetKeyState = Win32API.new("user32", "GetKeyState", "i", "i")
    GetCursorPos = Win32API.new("user32", "GetCursorPos", "p", "i")
    FindWindow = Win32API.new("user32", "FindWindow", "pp", "i")
    GetActiveWindow = Win32API.new("user32", "GetActiveWindow", "v", "i")
    ScreenToClient = Win32API.new("user32", "ScreenToClient", "lp", "b")
    GetPrivateProfileString = Win32API.new("kernel32", "GetPrivateProfileString", "pppplp", "l")

    title = "\0" * 256
    GetPrivateProfileString.call("Game", "Title", "", title, 256, ".\\Game.ini")
    title.delete!("\0")
    hwnd = FindWindow.call("RGSS Player", title)
    HWND = (hwnd == 0) ? FindWindow.call("RGSS Player", 0) : hwnd

    module_function

    def key_down?(key)
      GetKeyState.call(key) & 0x8000 != 0
    end

    def cursor_pos
      tagPOINT = "\0" * 8
      GetCursorPos.call(tagPOINT)
      ScreenToClient.call(HWND, tagPOINT)
      tagPOINT.unpack("L2")
    end
  end
end

module OJ
  process :frames_skip do |n|
    c = Graphics.frame_count + n
    Fiber.yield -> { Graphics.frame_count >= c }
  end

  process :graphics_update do
    n = Graphics.frame_count
    Fiber.yield -> { Graphics.frame_count > n }
  end

  process :key_press do |key|
    Fiber.yield -> { API.key_down?(key) }
  end

  process :key_trigger do |key|
    Fiber.yield -> { !API.key_down?(key) }
    Fiber.yield -> { API.key_down?(key) }
  end

  process :mouse_click_left do |key|
    Fiber.yield -> { !API.key_down?(0x01) }
    Fiber.yield -> { API.key_down?(0x01) }
    API.cursor_pos
  end

  process :mouse_click_right do |key|
    Fiber.yield -> { !API.key_down?(0x02) }
    Fiber.yield -> { API.key_down?(0x02) }
    API.cursor_pos
  end

  process :mouse_click_double do |key|
    ret = nil
    until ret
      mouse_click_left
      ret = select {
        mouse_click_left
        frames_skip(12)
      }.first
    end
    ret
  end
end
